#define HANDLE_ERROR(dom,msg,perr)\
{ printf ("%s:\n", #dom);\
if (perr) {perror (msg);}\
else {fprintf (stderr,"%s\n",msg);}\
goto error;}

#define HANDLE_ERROR_LK(dom,msg,perr)\
{ printf ("%s:\n", #dom);\
if (perr) {perror (msg);}\
else {fprintf (stderr,"%s\n",msg);}\
exit(EXIT_FAILURE);}

#define LOCK(mtx){\
    if (pthread_mutex_lock (&(mtx)) == -1)\
        HANDLE_ERROR_LK(#mtx, "Unable to lock",1);\
}

#define UNLOCK(mtx){\
    if (pthread_mutex_unlock (&(mtx)) == -1)\
        HANDLE_ERROR_LK(#mtx, "Unable to unlock",1);\
}

#define WAIT(sem){\
    if (sem_wait(&(sem)) == -1)\
        HANDLE_ERROR_LK(#sem, "Unable to wait",1);\
}

#define SIGNAL(sem){\
    if (sem_post(&(sem)) == -1)\
        HANDLE_ERROR_LK(#sem, "Unable to signal",1);\
}
#define CLEAR() printf("\033[2J")
/* rand.c */
char * get_rand_name ();
/* buffer.c */
filebuf * filebuf_init (int fd, enum fb_type type, int bnum ,size_t bsize, int numa_node);
int filebuf_destory(filebuf* fbuf);
int filebuf_trans_in2out (filebuf *fbuf);
int filebuf_trans_in2un (filebuf *fbuf);
int filebuf_trans_out2in (filebuf *fbuf);
int filebuf_trans_out2un (filebuf *fbuf);
/* file.c */
int file_init (char *i_dir_name, char *o_dir_name);
int file_get_in_fd ();
int file_get_out_fd ();
int file_clean ();
/* ring.c */
int filebuf_ring_init (filebuf_ring *ring);
filebuf *filebuf_ring_get (filebuf_ring *ring, enum fb_type btype);
int filebuf_ring_put (filebuf_ring *ring, filebuf *fbuf); 
/* threads.c */
int thread_init (int mt, int knum); 
int thread_create ();
int thread_join ();
/* heap.c */
int heap_init (filebuf_heap *heap, filebuf **bufs, int n);
int heap_get_min (filebuf_heap *heap, threadinfo *info, uint64 *b);